home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / C++ Exceptions / µShell / Core Utilities / ClassDesc.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-14  |  10.8 KB  |  278 lines  |  [TEXT/CWIE]

  1. #ifndef __CLASSDESC__
  2. #define __CLASSDESC__
  3. #pragma once
  4.  
  5. #ifndef __AEDATAMODEL__
  6. #include <AEDataModel.h>
  7. #endif
  8.  
  9. #include <stddef.h>
  10.  
  11. typedef SInt16 ClassID;
  12.  
  13. enum
  14. {
  15.     kUninitializedClassID    = 0,
  16.     kDeletedClassID            = -1,
  17.     
  18.     kInvalidClassOffset        = 1
  19. };
  20.  
  21. #ifndef qMultipleInheritance
  22. #define qMultipleInheritance    1
  23. #endif
  24.  
  25. typedef struct AEClassList AEClassList, *AEClassListPtr, **AEClassListHdl;
  26. typedef struct AEPropList  AEPropList,  *AEPropListPtr,  **AEPropListHdl;
  27.  
  28. class AEClassInfo;
  29. class AEPropInfo;
  30.  
  31. #if PRAGMA_ALIGN_SUPPORTED
  32. #pragma options align=mac68k
  33. #endif
  34.  
  35. class ClassDesc
  36. {
  37. public:
  38.     struct ObjectRef        // embed one of these in each object
  39.     {
  40.         ClassID    fClassID;        // the ID of the class
  41.         SInt16    fClassOffset;    // offset to real object
  42.  
  43.         ObjectRef();
  44.         ~ObjectRef();
  45.         
  46.         inline bool    IsInitialized()    { return fClassID > kUninitializedClassID; }
  47.     };
  48.  
  49.     static ClassDesc*    fgClassList;                // List of ClassDesc, indexed by class ID.
  50.     static ClassID        fgLastClassID;                // The last valid class ID.
  51.     
  52. protected:
  53. /*  0 */    void*                fDefaultConstructor;        // Default constructor for this class
  54.     
  55. /*  4 */    const ClassDesc*    fNextClassDesc;                // Link to next ClassDesc in list of all ClassDesc.
  56.  
  57. /*  8 */    const char*            fClassName;                    // Class name
  58.  
  59. /* 12 */    long                fClassSize;                    // size of class
  60.     
  61. /* 16 */    SInt16                fClassID;                    // Unique identifying class ID.
  62.     
  63. /* 18 */    const ClassDesc*    fBaseClass;                    // (first) base class
  64.     
  65. /* 22 */    const ClassDesc**    fBaseClassDescList;            // overflow list of base classes
  66.  
  67. /* 26 */    SInt16                fClassOffset;                // Offset of fClassID in real object
  68.  
  69. /* 28 */    const DescType*        fAEClassIDs;                // which AEOM classes do we implement
  70.  
  71. /* 32 */    AEClassListHdl        fAEClassInfo;                // cached info for above
  72.     
  73. public:
  74. //    ClassDesc(size_t size, size_t offset, char* name = nil, const ClassDesc* base_class = nil, const DescType* ae_classes = nil);
  75.     ClassDesc(size_t size, size_t offset, char* name = nil, const ClassDesc** base_List = nil, const DescType* ae_classes = nil);
  76.  
  77.     inline const char* GetClassName()            const    { return fClassName;     }
  78.     inline const ClassDesc* GetFirstBaseClass()    const    { return fBaseClass;     }
  79.     inline const ClassDesc* GetNextClassDesc()    const    { return fNextClassDesc; }
  80.     inline ClassID GetClassID()                    const    { return fClassID;          }
  81.     inline void SetClassID(ClassID theClassID)            { fClassID = theClassID; }
  82.  
  83.     void RegisterObject(ObjectRef& ref, void* object) const;
  84.  
  85.     static inline ClassDesc*    GetClassList()            { return fgClassList;     }
  86.     static inline ClassID        GetLastClassID()        { return fgLastClassID;     }
  87.     static inline ClassID        GetNumClasses()            { return fgLastClassID;     }
  88.  
  89. /*
  90.     AEClassListHdl    GetAEClasses()                     const;
  91.     bool            IsAEClass(DescType aClassID)    const;
  92.     
  93.     AEClassInfo*    GetAEClassInfo(DescType asClass = 0);
  94.     AEPropInfo*        GetAEPropInfo(DescType propID, DescType asClass = 0);
  95. */
  96. };
  97.  
  98. #if PRAGMA_ALIGN_SUPPORTED
  99. #pragma options align=reset
  100. #endif
  101.  
  102. enum {
  103.      kIllegalClassOffset    = 1     // this would be in the middle of the class
  104. };
  105.  
  106. #if qObjectInspector
  107. #define ClassOffset(name)    offsetof(name, fClassID)
  108. #else
  109. #define ClassOffset(name)    kIllegalClassOffset
  110. #endif
  111.  
  112. #define    DeclareClass(name)                                                                                \
  113.     private: static  ClassDesc            gClassDesc;                                                        \
  114.     private: typedef name                ThisClass;                                                        \
  115.     public:  static  inline ClassDesc*    GetClassDescStatic()    { return &gClassDesc; }                    \
  116.     public:  virtual const  ClassDesc*    GetClassDescDynamic() const
  117.  
  118. #define    DeclareClassAbstract(name)                                                                        \
  119.     private: static  ClassDesc            gClassDesc;                                                        \
  120.     private: typedef name                ThisClass;                                                        \
  121.     public:  static  inline ClassDesc*    GetClassDescStatic()    { return &gClassDesc; }                    \
  122.     public:  virtual const  ClassDesc*    GetClassDescDynamic() const = 0
  123.  
  124. #define    DeclareClassNoBase(name)                    \
  125.     DeclareClass(name)
  126.  
  127. #define    DeclareClassNoBaseAbstract(name)            \
  128.     DeclareClassAbstract(name)
  129.  
  130. #define    DeclareClassSingle(name, parent)            \
  131.     private: typedef parent Inherited;                \
  132.     DeclareClass(name)
  133.  
  134. #define    DeclareClassSingleAbstract(name, parent)    \
  135.     private: typedef parent Inherited;                \
  136.     DeclareClassAbstract(name)
  137.  
  138. #define    DeclareClass1Base(name, base1)                                DeclareClassSingle(name, base1)
  139. #define    DeclareClass1BaseAbstract(name, base1)                        DeclareClassSingleAbstract(name, base1)
  140.  
  141. #define    DeclareClass2Base(name, base1, base2)                        DeclareClass(name)
  142. #define    DeclareClass2BaseAbstract(name, base1, base2)                DeclareClassAbstract(name)
  143.  
  144. #define    DeclareClass3Base(name, base1, base2, base3)                DeclareClass(name)
  145. #define    DeclareClass3BaseAbstract(name, base1, base2, base3)        DeclareClassAbstract(name)
  146.  
  147.  
  148. #define DefineClass(name)                                                                                        \
  149.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, (const ClassDesc**) nil);    \
  150.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  151.  
  152.  
  153. #define DefineClassNoBase(name)                                                                                        \
  154.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, (const ClassDesc**) nil);    \
  155.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  156.  
  157. #define DefineClassNoBaseAbstract(name)                                                                                \
  158.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, (const ClassDesc**) nil)
  159.  
  160. #define DefineClassSingle(name)                                                                                        \
  161.     static ClassDesc* __##name##_base_list[] = {                                                                    \
  162.         name::Inherited::GetClassDescStatic(), nil};    \
  163.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  164.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  165.  
  166. #define DefineClassSingleAE(name, classlist)            \
  167.     static ClassDesc* __##name##_base_list[] = {                \
  168.         name::Inherited::GetClassDescStatic(), nil};    \
  169.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list, classlist);    \
  170.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  171.  
  172. #define DefineClassSingleAbstract(name)                    \
  173.     static ClassDesc* __##name##_base_list[] = {                \
  174.         name::Inherited::GetClassDescStatic(), nil};    \
  175.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list)
  176.  
  177. #define DefineClassSingleAbstractAE(name, classlist)    \
  178.     static ClassDesc* __##name##_base_list[] = {                \
  179.         name::Inherited::GetClassDescStatic(), nil};    \
  180.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list, classlist)
  181.  
  182. #define DefineClassSingleAbstractAE1(name, classID)            \
  183.     static const DescType ae_classes[] = { classID, 0 };    \
  184.     static ClassDesc* __##name##_base_list[] = {                    \
  185.         name::Inherited::GetClassDescStatic(), nil};        \
  186.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list, ae_classes)
  187.  
  188. #define DefineClassSingleAbstractAE2(name, classID1, classID2)        \
  189.     static const DescType ae_classes[] = { classID1, classID2, 0 };    \
  190.     static ClassDesc* __##name##_base_list[] = {                            \
  191.         name::Inherited::GetClassDescStatic(), nil};                \
  192.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list, ae_classes)
  193.  
  194. #define DefineClassSingleAbstractAE3(name, classID1, classID2, classID3)        \
  195.     static const DescType ae_classes[] = { classID1, classID2, classID3, 0 };    \
  196.     static ClassDesc* __##name##_base_list[] = {                                        \
  197.         name::Inherited::GetClassDescStatic(), nil};                            \
  198.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list, ae_classes)
  199.  
  200. #define DefineClass1Base(name, base1)                    \
  201.     static ClassDesc* __##name##_base_list[] = {                \
  202.         base1::GetClassDescStatic(), nil};                \
  203.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  204.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  205.  
  206. #define DefineClass1BaseAbstract(name, base1)            \
  207.     static ClassDesc* __##name##_base_list[] = {                \
  208.         base1::GetClassDescStatic(), nil};                \
  209.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list)
  210.  
  211. #define DefineClass2Base(name, base1, base2)            \
  212.     static ClassDesc* __##name##_base_list[] = {                \
  213.         base1::GetClassDescStatic(),                    \
  214.         base2::GetClassDescStatic(), nil};                \
  215.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  216.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  217.  
  218. #define DefineClass2BaseAbstract(name, base1, base2)    \
  219.     static ClassDesc* __##name##_base_list[] = {        \
  220.         base1::GetClassDescStatic(),                    \
  221.         base2::GetClassDescStatic(), nil};                \
  222.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list)
  223.  
  224. #define DefineClass3Base(name, base1, base2, base3)        \
  225.     static ClassDesc* __##name##_base_list[] = {                \
  226.         base1::GetClassDescStatic(),                    \
  227.         base2::GetClassDescStatic(),                     \
  228.         base3::GetClassDescStatic(), nil};                \
  229.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  230.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  231.  
  232. #define DefineClass3BaseAbstract(name, base1, base2, base3)        \
  233.     static ClassDesc* __##name##_base_list[] = {                \
  234.         base1::GetClassDescStatic(),                    \
  235.         base2::GetClassDescStatic(),                     \
  236.         base3::GetClassDescStatic(), nil};                \
  237.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list)
  238.  
  239. #define DefineClass4Base(name, base1, base2, base3, base4) \
  240.     static ClassDesc* __##name##_base_list[] = {                \
  241.         base1::GetClassDescStatic(),                    \
  242.         base2::GetClassDescStatic(),                     \
  243.         base3::GetClassDescStatic(),                     \
  244.         base4::GetClassDescStatic(), nil};                \
  245.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  246.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  247.  
  248. #define DefineClass4BaseAbstract(name, base1, base2, base3, base4) \
  249.     static ClassDesc* __##name##_base_list[] = {                \
  250.         base1::GetClassDescStatic(),                    \
  251.         base2::GetClassDescStatic(),                     \
  252.         base3::GetClassDescStatic(),                     \
  253.         base4::GetClassDescStatic(), nil};                \
  254.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);
  255.  
  256. #define DefineClass5Base(name, base1, base2, base3, base4, base5) \
  257.     static ClassDesc* __##name##_base_list[] = {                \
  258.         base1::GetClassDescStatic(),                    \
  259.         base2::GetClassDescStatic(),                     \
  260.         base3::GetClassDescStatic(),                     \
  261.         base4::GetClassDescStatic(),                     \
  262.         base5::GetClassDescStatic(), nil};                \
  263.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);    \
  264.     const ClassDesc* name::GetClassDescDynamic()  const { return &gClassDesc; }
  265.  
  266. #define DefineClass5BaseAbstract(name, base1, base2, base3, base4, base5) \
  267.     static ClassDesc* __##name##_base_list[] = {                \
  268.         base1::GetClassDescStatic(),                    \
  269.         base2::GetClassDescStatic(),                     \
  270.         base3::GetClassDescStatic(),                     \
  271.         base4::GetClassDescStatic(),                     \
  272.         base5::GetClassDescStatic(), nil};                \
  273.     ClassDesc name::gClassDesc(sizeof(name), ClassOffset(name), #name, __##name##_base_list);
  274.  
  275. #endif // __CLASSDESC__
  276.  
  277.  
  278.